"""
时间：2024/2/25下午3点
天气：阴, 地面有积雪
说明：为了统一，将test01.py中imgori替换成image;
     setPixmap打开图片闪退，添加h, w, ch = frame.shape
                            bytesPerLine = ch * w进行位置限制无效；(最终在self.ui.label_4.setPixmap(QtGui.QPixmap.fromImage(image))添加ui.解决);
     2/26早7点，打开和保存正常，进行templateMatch又出现卡死;
     2/29早，更改不同的图片进行匹配，会随机报错 “UnboundLocalError: ",猜测是访问局部变量和全局变量出现异常;
     2/29 为了在图片上显示中文字符，引入PIL库；
"""
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog, QApplication, QMainWindow
from PIL import Image, ImageDraw, ImageFont
from PyQt5.QtGui import QImage, QIcon
from untitled import *
import numpy as np
import cv2 as cv
import sys
import ctypes

ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.filename = None  # Will hold the image address location
        self.tmp = None  # Will hold the temporary image for display
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.ui.pushButton_4.clicked.connect(self.templateMatch)
        self.ui.pushButton_5.clicked.connect(self.multipleMatch)
        self.ui.pushButton_6.clicked.connect(self.only_one_rectangle)
        self.ui.pushButton_7.clicked.connect(self.loadImage)
        self.ui.pushButton_8.clicked.connect(self.savePhoto)
        self.show()

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton and self.isMaximized() == False:
            self.m_flag = True
            self.m_Position = event.globalPos() - self.pos()  # 获取鼠标相对窗口的位置
            event.accept()
            self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))  # 更改鼠标图标

    def mouseMoveEvent(self, mouse_event):
        if QtCore.Qt.LeftButton and self.m_flag:
            self.move(mouse_event.globalPos() - self.m_Position)  # 更改窗口位置
            mouse_event.accept()

    def mouseReleaseEvent(self, mouse_event):
        self.m_flag = False
        self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))

    def loadImage(self):
        self.filename = QFileDialog.getOpenFileName(filter="Image(*.*)")[0]
        self.imageori = cv.imread(self.filename)
        self.setPhoto(self.imageori)

    def setPhoto(self, imageori):
        self.tmp = imageori
        frame = cv.cvtColor(self.tmp, cv.COLOR_BGR2RGB)
        imageori = QImage(frame, frame.shape[1], frame.shape[0], frame.strides[0], QImage.Format_RGB888)
        self.ui.label_4.setPixmap(QtGui.QPixmap.fromImage(imageori))

    def templateMatch(self):
        imgtemp = cv.imread("image\\3.jpg")
        assert imgtemp is not None, "图片读取失败，请检查路径"
        print(type(self.imageori))
        self.result = cv.matchTemplate(self.imageori, imgtemp, cv.TM_CCOEFF_NORMED)
        minval, maxval, minloc, maxloc = cv.minMaxLoc(self.result)
        # cv.imshow('0',self.result)
        print(minval)
        print(maxval)
        print(minloc)
        print(maxloc)
        self.w = imgtemp.shape[1]
        self.h = imgtemp.shape[0]
        imgori_0 = self.imageori.copy()
        output = cv.rectangle(imgori_0, maxloc, (maxloc[0] + self.w, maxloc[1] + self.h), (0, 200, 0), 2)
        # cv.imshow('1',self.imageori)
        self.setPhoto(output)

    def multipleMatch(self):
        threshold = .80
        # cv.imshow('2', self.result)
        self.yloc, self.xloc = np.where(self.result >= threshold)
        print(self.xloc)
        imgori_1 = self.imageori.copy()
        if self.xloc.any():
            w = self.w
            h = self.h
            for (x, y) in zip(self.xloc, self.yloc):
                output1 = cv.rectangle(imgori_1, (x, y), (x + w, y + h), (0, 0, 222), 2)
            self.setPhoto(output1)
        else:
            print('模板不可能在这里')
            imgPIL = Image.fromarray(cv.cvtColor(imgori_1, cv.COLOR_BGR2RGB))
            drawPIL = ImageDraw.Draw(imgPIL)
            textSize = 52
            fontText = ImageFont.truetype("font/simhei.ttf", textSize, encoding="utf-8")
            pos = (50, 350)
            text = '模板不可能在这里'
            color = (251, 210, 106)
            drawPIL.text(pos, text, color, font=fontText)
            imgPutText = cv.cvtColor(np.asarray(imgPIL), cv.COLOR_RGB2BGR)
            self.setPhoto(imgPutText)

    def only_one_rectangle(self):
        rectangles = []
        for (x, y) in zip(self.xloc, self.yloc):
            rectangles.append([int(x), int(y), int(self.w), int(self.h)])

        rectangles, weights = cv.groupRectangles(rectangles, 1, 0.2)
        print("蓝色方框数是", len(rectangles))
        imgori_2 = self.imageori.copy()

        if len(rectangles) > 0:
            for (x, y, w, h) in rectangles:
                print(x)
                print(y)
                print(w)
                print(h)
                output2 = cv.rectangle(imgori_2, (x, y), (x + w, y + h), (200, 0, 0), 2)
            self.setPhoto(output2)
        else:
            print('输入图像和模板完全一致或完全不一致')
            imgPIL = Image.fromarray(cv.cvtColor(imgori_2, cv.COLOR_BGR2RGB))
            drawPIL = ImageDraw.Draw(imgPIL)
            textSize = 52
            fontText = ImageFont.truetype("font/simhei.ttf", textSize, encoding="utf-8")
            pos = (5, 350)
            text = '与模板完全一致或完全不一致'
            color = (0, 47, 167)
            drawPIL.text(pos, text, color, font=fontText)
            imgPutText = cv.cvtColor(np.asarray(imgPIL), cv.COLOR_RGB2BGR)
            self.setPhoto(imgPutText)

    # def update(self):
    #     self.setPhoto(self.imageori)

    def savePhoto(self):
        filename = QFileDialog.getSaveFileName(filter="JPG(*.jpg);;PNG(*.png);;TIFF(*.tiff);;BMP(*.bmp)")[0]
        cv.imwrite(filename, self.tmp)
        print('Image saved as:', self.filename)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.setWindowTitle(u'模板匹配')
    win.setWindowIcon(QIcon('icon\\logo.png'))
    sys.exit(app.exec_())
